package com.cw.reflect4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            InvocationTargetException, IllegalAccessException {
    /*    Class类中用于获取成员方法的方法
        Method[] getMethods():返回所有公共成员方法对象的数组，包括继承的
        Method[] getDeclaredMethods():返回所有成员方法对象的数组，不包括继承的
        Method[] getMethod(String name, Class < ?>...parameterTypes):返回单个公共成员方法对象
        Method[] getDeclaredMethod(String name, Class < ?>...parameterTypes):返回单个成员方法对象

        Method类中用于创建对象的方法
        Object invoke (Object obj, Object...args):运行方法
        参数一：用obj对象调用该方法
        参数二：调用方法的传递的参数（如果没有就不写）
        返回值：方法的返回值（如果没有就不写）

        获取方法的修饰符
        获取方法的名字
        获取方法的形参
        获取方法的返回值
        获取方法抛出的异常*/

        //1. 获取class字节码文件对象
        Class clazz = Class.forName("com.cw.reflect4.Student");

        //2. 获取所有公共方法对象(包含父类中所有的公共方法)
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("===========================");

        //3. 获取所有方法对象(不能获取父类的，但是可以获取本类中私有的方法)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("===========================");

        // 获取指定的单一方法
        Method sleep = clazz.getMethod("sleep");
        System.out.println(sleep);
        System.out.println("===========================");

        // 获取任意的单一方法
        Method eat = clazz.getDeclaredMethod("eat",String.class);
        System.out.println(eat);
        System.out.println("===========================");

        // 获取方法的修饰符
        int modifiers = eat.getModifiers();
        System.out.println(modifiers);
        System.out.println("===========================");

        // 获取方法的名字
        String name = eat.getName();
        System.out.println(name);
        System.out.println("===========================");

        // 获取方法的形参
        Parameter[] parameters = eat.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        System.out.println("===========================");

        // 获取方法抛出的异常
        Class<?>[] exceptionTypes = eat.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }
        System.out.println("===========================");

        // 方法运行
        /*Method类中用于创建对象的方法
        Object invoke (Object obj, Object...args):运行方法
        参数一：用obj对象调用该方法
        参数二：调用方法的传递的参数（如果没有就不写）
        返回值：方法的返回值（如果没有就不写）*/
        Student s = new Student();

        //参数一s：代表方法的调用者
        //参数二"好吃的"：表示在调用方法的时候传递的参数
        // 临时取消权限校验
        eat.setAccessible(true);
//        Object o = eat.invoke(s, "好吃的");
        String o = (String) eat.invoke(s, "好吃的");
        System.out.println(o);
    }
}
